#pragma once

#include <iterator>
#include <tr1/functional>

#include "precomp.h"


QFL_NAMESPACE_BEGIN

    template <typename _Type>
	class istream_filter_iterator
		: public std::iterator<std::input_iterator_tag, _Type>
	{
	private:
		typedef istream_filter_iterator _Myt;
		typedef std::tr1::function<_Type(std::istream&)> _Functor;

	public:
		_Myt()
			: pistr_(0)
		{
		}
		//template <typename _WrapperType>
		_Myt(std::istream& istr,_Functor filter)
			: pistr_(&istr),filter_(filter)
		{
			_GetVal();
		}
		_Type& operator*()
		{
			return val_;
		}
		_Type& operator->()
		{
			return (&**this);
		}
		_Myt& operator++()
		{
			_GetVal();
			return *this;
		}
		_Myt operator++(int)
		{
			_Myt tmp = *this;
			++*this;
			return (tmp);
		}
		bool operator==(const _Myt& _Right) const
		{	// test for iterator equality
			return (pistr_ == _Right.pistr_);
		}

	protected:
		_Functor filter_;
		std::istream *pistr_;
		_Type val_;

		void _GetVal()
		{
			if (pistr_)
			{
				//assert(wrapper.
			    val_ = filter_(*pistr_);
				if (pistr_->eof()) pistr_=0;
			}
		}
	};

	template<typename _Elem>
	inline
	bool operator!=(
			const istream_filter_iterator<_Elem>& _Left,
			const istream_filter_iterator<_Elem>& _Right)
	{	// test for istream_iterator equality
		return !(_Left==_Right);
	}



//end namespace
QFL_NAMESPACE_END
